﻿using System;
using System.Linq;
using Dgg.Anug.Cqrs.Core.Domain.Admin;
using Dgg.Anug.Cqrs.Core.Domain.Admin.Events;
using Dgg.Anug.Cqrs.Core.Infrastructure.Data;
using Dgg.Anug.Cqrs.Core.Infrastructure.Eventing;
using Raven.Client;

namespace Dgg.Anug.Cqrs.Core.Application.Admin.Services.Handlers
{
	public class SolutionDeletedPersister : IHandler<SolutionDeleted>
	{
		private readonly IEventSession _eventSession;

		public SolutionDeletedPersister(IEventSession eventSession)
		{
			_eventSession = eventSession;
		}

		public bool Handle(SolutionDeleted e)
		{
			_eventSession.Save(e);
			return true;
		}
	}

	public class SolutionDeletedSnapshotUpdater : IHandler<SolutionDeleted>
	{
		private readonly ISnapshotSession _snapshotSession;

		public SolutionDeletedSnapshotUpdater(ISnapshotSession snapshotSession)
		{
			_snapshotSession = snapshotSession;
		}

		public bool Handle(SolutionDeleted e)
		{
			_snapshotSession.Delete<Solution>(s => s.Id == e.ReceiverId);

			return true;
		}
	}

	public class SolutionDeletedQueryUpdater : IHandler<SolutionDeleted>
	{
		private readonly IDocumentSession _modelSession;

		public SolutionDeletedQueryUpdater(IDocumentSession modelSession)
		{
			_modelSession = modelSession;
		}

		public bool Handle(SolutionDeleted e)
		{
			var toBeDeleted = _modelSession.Single<Presentation.Models.Admin.Solution>(e.ReceiverId);
			_modelSession.Delete(toBeDeleted);

			return true;
		}
	}

	public class DeleteForAssignedVersionsQueryUpdater : IHandler<SolutionDeleted>
	{
		private readonly IDocumentSession _modelSession;

		public DeleteForAssignedVersionsQueryUpdater(IDocumentSession modelSession)
		{
			_modelSession = modelSession;
		}

		public bool Handle(SolutionDeleted e)
		{
			Presentation.Models.Admin.AppVersion[] assignedVersions = _modelSession.Query<Presentation.Models.Admin.AppVersion, Queries.VersionsAssignedToSolution>()
					.Where(v => v.AssignedTo.Id == e.ReceiverId.ToString())
					.ToArray();

			Array.ForEach(assignedVersions, version => version.AssignedTo = null);

			return true;
		}
	}

	public class DeleteForAssignedBuildsQueryUpdater : IHandler<SolutionDeleted>
	{
		private readonly IDocumentSession _modelSession;

		public DeleteForAssignedBuildsQueryUpdater(IDocumentSession modelSession)
		{
			_modelSession = modelSession;
		}

		public bool Handle(SolutionDeleted e)
		{
			Presentation.Models.Admin.Build[] assignedBuilds = _modelSession.Query<Presentation.Models.Admin.Build, Queries.BuildsAssignedToSolution>()
					.Where(v => v.AssignedTo.Id == e.ReceiverId.ToString())
					.ToArray();

			Array.ForEach(assignedBuilds, build => build.AssignedTo = null);

			return true;
		}
	}
}
